package net.cnki.sunny.aop;

import cn.hutool.json.JSONUtil;
import net.cnki.sunny.annotation.OperateLog;
import net.cnki.sunny.common.ResultVO;
import net.cnki.sunny.model.vo.TextDataVO;
import net.cnki.sunny.model.enums.OperateLogEnums;
import net.cnki.sunny.service.OperateLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Enumeration;

@Component
@Aspect
public class OperateLogAspect {

    @Autowired
    private OperateLogService operateLogService;

    @AfterReturning(value = "operateLogPointcut()",returning = "result")
    public void saveOperateLg(JoinPoint joinPoint,Object result){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        Enumeration<String> attributeNames = httpServletRequest.getAttributeNames();
        //body参数
        Object[] args = joinPoint.getArgs();

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        OperateLog annotation = method.getAnnotation(OperateLog.class);
        Integer operateType = annotation.operateType().getCode();
        if(OperateLogEnums.OperateType.OPERATE_SEARCH.getCode().equals(operateType) && !StringUtils.hasLength(JSONUtil.parseObj(args[0]).getStr("keywords"))){
            return;
        }

        ResultVO resultVO  = JSONUtil.toBean(JSONUtil.parseObj(result),ResultVO.class);
        TextDataVO data  = JSONUtil.toBean(JSONUtil.parseObj(resultVO.getData()), TextDataVO.class);

        net.cnki.sunny.model.entity.OperateLog operateLog = new net.cnki.sunny.model.entity.OperateLog();
        operateLog.setOperateType(operateType);
        operateLog.setOperateTime(new Date(System.currentTimeMillis()));
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        operateLog.setUserId(JSONUtil.parseObj(authentication.getPrincipal()).getInt("id"));
        operateLog.setUsername(JSONUtil.parseObj(authentication.getPrincipal()).getStr("username"));
        if(OperateLogEnums.OperateType.OPERATE_SEARCH.getCode().equals(operateType) ){
            operateLog.setContent(JSONUtil.parseObj(args[0]).getStr("keywords"));
        }else{
            operateLog.setContent(data.getTitle());
        }
        operateLog.setRelateId(data.getId());
        operateLogService.addOperateLog(operateLog);

    }

    /**
     * 操作日志切点位置
     */
    @Pointcut("@annotation(net.cnki.sunny.annotation.OperateLog)")
    public void operateLogPointcut() {
    }
}
